package cn.rebeater.navigationclient.ui.notifications;

import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentResultListener;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;

import java.util.ArrayList;

import cn.rebeater.navigationclient.R;
import cn.rebeater.navigationclient.ui.dashboard.NavigationData;

public class NotificationsFragment extends Fragment {

    private NotificationsViewModel notificationsViewModel;
    private LineChart chart_ab;
    private ArrayList<Entry> list_ab_x,list_ab_y,list_ab_z;
    private LineDataSet lds_ab_x,lds_ab_y,lds_ab_z;
    private LineData ld_ab;


    private LineChart chart_gb;
    private ArrayList<Entry> list_gb_x,list_gb_y,list_gb_z;
    private LineDataSet lds_gb_x,lds_gb_y,lds_gb_z;
    private LineData ld_gb;

    private LineChart chart_pos_std;
    private ArrayList<Entry> list_pos_std_x,list_pos_std_y,list_pos_std_z;
    private LineDataSet lds_pos_std_x,lds_pos_std_y,lds_pos_std_z;
    private LineData ld_pos_std;

    LineChart chart_odo;
    private LineDataSet lds_odo;
    private ArrayList<Entry> list_odo;
    private LineData ld_odo;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        notificationsViewModel =
                new ViewModelProvider(this).get(NotificationsViewModel.class);
        View root = inflater.inflate(R.layout.fragment_notifications, container, false);
        setHasOptionsMenu(true);
        chart_gb = root.findViewById(R.id.chart_gb);
        chart_ab = root.findViewById(R.id.chart_ab);
        chart_pos_std = root.findViewById(R.id.chart_pos_std);
        chart_odo = root.findViewById(R.id.chart_odo_kd);
        initChart();

        getParentFragmentManager().setFragmentResultListener("requestKeyForBias", this, new FragmentResultListener() {
            @Override
            public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
                double[] result = bundle.getDoubleArray("bundleKey");
                notificationsViewModel.addBias(result);
            }
        });
        getParentFragmentManager().setFragmentResultListener("requestKeyForStd", this, new FragmentResultListener() {
            @Override
            public void onFragmentResult(@NonNull String key, @NonNull Bundle bundle) {
                double[] result = bundle.getDoubleArray("bundleKey");
                notificationsViewModel.addStd(result);
            }
        });
        notificationsViewModel.getBias().observe(getViewLifecycleOwner(), new Observer<double []>() {
            @Override
            public void onChanged(@Nullable double [] s) {
                assert s != null;
                lds_odo.addEntry(new Entry((float) s[1], (float) s[8]/1e4f));
                lds_odo.notifyDataSetChanged();
                ld_odo.notifyDataChanged();
                chart_odo.notifyDataSetChanged();
                chart_odo.invalidate();

                lds_gb_x.addEntry(new Entry((float) s[1], (float) s[2]));
                lds_gb_x.notifyDataSetChanged();
                lds_gb_y.addEntry(new Entry((float) s[1], (float) s[3]));
                lds_gb_y.notifyDataSetChanged();
                lds_gb_z.addEntry(new Entry((float) s[1], (float) s[4]));
                lds_gb_z.notifyDataSetChanged();
                ld_gb.notifyDataChanged();
                chart_gb.notifyDataSetChanged();
                chart_gb.invalidate();

                lds_ab_x.addEntry(new Entry((float) s[1], (float) s[5]));
                lds_ab_x.notifyDataSetChanged();
                lds_ab_y.addEntry(new Entry((float) s[1], (float) s[6]));
                lds_ab_y.notifyDataSetChanged();
                lds_ab_z.addEntry(new Entry((float) s[1], (float) s[7]));
                lds_ab_z.notifyDataSetChanged();
                ld_ab.notifyDataChanged();
                chart_ab.notifyDataSetChanged();
                chart_ab.invalidate();
            }
        });

        notificationsViewModel.getStd().observe(getViewLifecycleOwner(), new Observer<double []>() {
            @Override
            public void onChanged(@Nullable double [] s) {
                assert s != null;
                lds_pos_std_x.addEntry(new Entry((float) s[1], (float) s[2]/1e4f));
                lds_pos_std_x.notifyDataSetChanged();
                lds_pos_std_y.addEntry(new Entry((float) s[1], (float)s[3]/1e4f));
                lds_pos_std_y.notifyDataSetChanged();
                lds_pos_std_z.addEntry(new Entry((float)s[1], (float)s[4]/1e4f));
                lds_pos_std_z.notifyDataSetChanged();
                ld_pos_std.notifyDataChanged();
                chart_pos_std.notifyDataSetChanged();
                chart_pos_std.invalidate();
            }
        });
        return root;
    }



    void initAttiChart(){
        ld_pos_std = new LineData();
        list_pos_std_x = new ArrayList<>();
        lds_pos_std_x = new LineDataSet(list_pos_std_x, "x");
        lds_pos_std_x.setDrawCircles(false);
        lds_pos_std_x.setColor(Color.RED);
        lds_pos_std_x.setDrawValues(false);
        list_pos_std_y= new ArrayList<>();
        lds_pos_std_y = new LineDataSet(list_pos_std_y, "y");
        lds_pos_std_y.setDrawCircles(false);
        lds_pos_std_y.setColor(Color.GREEN);
        lds_pos_std_y.setDrawValues(false);
        list_pos_std_z = new ArrayList<>();
        lds_pos_std_z = new LineDataSet(list_pos_std_z, "z");
        lds_pos_std_z.setDrawCircles(false);
        lds_pos_std_z.setColor(Color.BLUE);
        lds_pos_std_z.setDrawValues(false);
        ld_pos_std.addDataSet(lds_pos_std_x);
        ld_pos_std.addDataSet(lds_pos_std_y);
        ld_pos_std.addDataSet(lds_pos_std_z);
        chart_pos_std.setData(ld_pos_std);
        Description description = new Description();
        description.setEnabled(false);
        chart_pos_std.setDescription(description);
    }
    void initAcceBiasChart(){
        ld_ab= new LineData();
        list_ab_x = new ArrayList<>();
        lds_ab_x = new LineDataSet(list_ab_x, "x");
        lds_ab_x.setDrawCircles(false);
        lds_ab_x.setColor(Color.RED);
        lds_ab_x.setDrawValues(false);

        list_ab_y = new ArrayList<>();
        lds_ab_y = new LineDataSet(list_ab_y, "y");
        lds_ab_y.setDrawCircles(false);
        lds_ab_y.setColor(Color.GREEN);
        lds_ab_y.setDrawValues(false);

        list_ab_z = new ArrayList<>();
        lds_ab_z = new LineDataSet(list_ab_z, "z");
        lds_ab_z.setDrawCircles(false);
        lds_ab_z.setColor(Color.BLUE);
        lds_ab_z.setDrawValues(false);

        ld_ab.addDataSet(lds_ab_x);
        ld_ab.addDataSet(lds_ab_y);
        ld_ab.addDataSet(lds_ab_z);
        chart_ab.setData(ld_ab);
        Description description = new Description();
        description.setEnabled(false);
        chart_ab.setDescription(description);
    }
    void initGyroBiasChart(){

        ld_gb= new LineData();
        list_gb_x = new ArrayList<>();
        lds_gb_x = new LineDataSet(list_gb_x, "x");
        lds_gb_x.setDrawCircles(false);
        lds_gb_x.setColor(Color.RED);
        lds_gb_x.setDrawValues(false);

        list_gb_y = new ArrayList<>();
        lds_gb_y = new LineDataSet(list_gb_y, "y");
        lds_gb_y.setDrawCircles(false);
        lds_gb_y.setColor(Color.GREEN);
        lds_gb_y.setDrawValues(false);

        list_gb_z = new ArrayList<>();
        lds_gb_z = new LineDataSet(list_gb_z, "z");
        lds_gb_z.setDrawCircles(false);
        lds_gb_z.setColor(Color.BLUE);
        lds_gb_z.setDrawValues(false);

        ld_gb.addDataSet(lds_gb_x);
        ld_gb.addDataSet(lds_gb_y);
        ld_gb.addDataSet(lds_gb_z);
        chart_gb.setData(ld_gb);
        Description description = new Description();
        description.setEnabled(false);
        chart_gb.setDescription(description);
    }
    void initOdoChart(){
        ld_odo = new LineData();
        list_odo = new ArrayList<>();
        lds_odo = new LineDataSet(list_odo, "kd");
        lds_odo.setDrawCircles(false);
        lds_odo.setColor(Color.RED);
        lds_odo.setDrawValues(false);

        ld_odo.addDataSet(lds_odo);
        chart_odo.setData(ld_odo);
        Description description = new Description();
        description.setText("Odometer scale factor");
        description.setEnabled(true);
        chart_odo.setDescription(description);

    }

    void initChart() {

        initGyroBiasChart();
        initAcceBiasChart();
        initAttiChart();
        initOdoChart();
    }

    void clearChart(){
        if(chart_gb!=null){
            lds_gb_x.clear();
            lds_ab_x.notifyDataSetChanged();
            lds_gb_y.clear();
            lds_ab_y.notifyDataSetChanged();
            lds_gb_z.clear();
            lds_ab_z.notifyDataSetChanged();
            ld_gb.notifyDataChanged();
            chart_gb.notifyDataSetChanged();
            chart_gb.invalidate();

        }
        if(chart_ab!=null){
            lds_ab_x.clear();
            lds_ab_x.notifyDataSetChanged();
            lds_ab_y.clear();
            lds_ab_y.notifyDataSetChanged();
            lds_ab_z.clear();
            lds_ab_z.notifyDataSetChanged();
            ld_ab.notifyDataChanged();
            chart_ab.notifyDataSetChanged();
            chart_ab.invalidate();

        }
        if(chart_pos_std!=null){
            lds_pos_std_x.clear();
            lds_pos_std_x.notifyDataSetChanged();
            lds_pos_std_y.clear();
            lds_pos_std_y.notifyDataSetChanged();
            lds_pos_std_z.clear();
            lds_pos_std_z.notifyDataSetChanged();
            ld_pos_std.notifyDataChanged();
            chart_pos_std.notifyDataSetChanged();
            chart_pos_std.invalidate();
        }
        if(chart_odo !=null){
            lds_odo.clear();
            lds_odo.notifyDataSetChanged();
            chart_odo.notifyDataSetChanged();
            chart_odo.invalidate();
        }

    }
    @Override
    public void onDestroy(){
        super.onDestroy();
        clearChart();
        chart_pos_std.clear();
        chart_gb.clear();
        chart_ab.clear();
        chart_odo.clear();
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.clear_chart:
                clearChart();
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.chart_menu, menu);
    }

}